package com.lms.logistics_management_system.service;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lms.logistics_management_system.common.Constants;
import com.lms.logistics_management_system.common.Result;
import com.lms.logistics_management_system.controller.dto.*;
import com.lms.logistics_management_system.entity.Diagnostic;
import com.lms.logistics_management_system.entity.Doctor;
import com.lms.logistics_management_system.entity.Measure;
import com.lms.logistics_management_system.exception.ServiceException;
import com.lms.logistics_management_system.mapper.*;
import com.lms.logistics_management_system.utils.TokenUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class DoctorService extends ServiceImpl<DoctorMapper, Doctor> {

    @Autowired
    private DoctorMapper doctorMapper;
    @Autowired
    private DiagnosticMapper diagnosticMapper;
    @Autowired
    private MeasureMapper measureMapper;
    @Autowired
    private ReservationItemMapper reservationItemMapper;

    @Autowired
    private ReservationMapper reservationMapper;
    public boolean saveUser(Doctor doctor){
        try{
            if(doctor.getDoctorId()==null){
                //没有id代表新增
                return save(doctor);

            }else{
                //有id代表更新
                return doctorMapper.updateByDoctorId(doctor);
            }
        }catch (Exception se){
            System.out.println(se);
            throw new ServiceException(Constants.CODE_500,"用户数据保存失败！");
        }

    }

    public Map<String, Object> login(String username, String password) {
        Doctor one=getUserInfo(username,password);
        if(one!=null) {
            Map<String,Object>res=new HashMap<>();
            DoctorDto doctorDto=new DoctorDto();
            //设置token,id作为签，password作为验证
            String token = TokenUtils.generateToken(one.getDoctorId().toString(), one.getDoctorPassword());
            doctorDto.setToken(token);
            BeanUtils.copyProperties(one, doctorDto);//将user内容copy到doctorDto中去
            res.put("data",doctorDto);
            //判断是否为管理员、
            if(one.getDoctorIsAdmin()==0){
                //用户登录
                res.put("is_admin",0);
            }else {
                //管理员登录
                res.put("is_admin",1);
            }
            return res;
        }else{
            throw new ServiceException(Constants.CODE_600,"用户名或密码错误");
        }
    }

    private Doctor getUserInfo(String username,String password){
        int doctorId=Integer.parseInt(username);
        QueryWrapper queryWrapper=new QueryWrapper<Doctor>();
        queryWrapper.eq("doctor_id",doctorId);
        if(!StrUtil.isBlank(password)) {
            queryWrapper.eq("doctor_password", password);
        }
        Doctor one;
        try {
            one= getOne(queryWrapper);
            return one;
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException(Constants.CODE_500,"用户名或密码错误");
        }
    }
    //根据doctorId获取医生信息
    public Doctor getByDoctorId(Integer doctorId){
        System.out.println("=========================doctorId:"+doctorId);
        return doctorMapper.getByDoctorId(doctorId);
    }

    //根据doctorId进行删除
    public boolean removeByDoctorId(Integer doctorId) {
        return doctorMapper.removeByDoctorId(doctorId);
    }


    //批量删除
    public boolean removeByDoctorIds(List<Integer> doctorIds) {
        return doctorMapper.removeByDoctorIds(doctorIds);
    }

    public Result changePassword(Integer doctorId, String password, String newpassword) {
        // 检查password和原来的是否匹配
        //获取个人信息
        Doctor doctor = getByDoctorId(doctorId);
        if(StrUtil.equals(doctor.getDoctorPassword(),password)){
            doctor.setDoctorPassword(newpassword);
            doctorMapper.updateByDoctorId(doctor);
            return Result.success();
        }else {
            return Result.error(Constants.CODE_600,"老密码错误!修改失败！");
        }

    }

    //将departmentItemDto类整理为measure类
    public List<DiagnosticResult> change(List<DepartmentItemDto> departmentItemDto){
        Map<Integer, DiagnosticResult> resultMap = new HashMap<>();
        for (DepartmentItemDto departmentItem : departmentItemDto) {
            int itemId = departmentItem.getItemId();
            DiagnosticResult diagnosticResult = resultMap.get(itemId);
            if (diagnosticResult == null) {
                diagnosticResult = new DiagnosticResult();
                diagnosticResult.setItemId(itemId);
                diagnosticResult.setItemName(departmentItem.getItemName());
                diagnosticResult.setMeasureResultList(new ArrayList<>());
                resultMap.put(itemId, diagnosticResult);
            }
            if (departmentItem.getMeasureResult() != null) {
                diagnosticResult.setDiagnosticResult(departmentItem.getDiagnosticResult());
            }
            MeasureResult measureResult = new MeasureResult();
            measureResult.setMeasureKindId(departmentItem.getMeasureKindId());
            measureResult.setMeasureKindName(departmentItem.getMeasureKindName());
            measureResult.setMeasureKindUnits(departmentItem.getMeasureKindUnits());
            measureResult.setMeasureResult(departmentItem.getMeasureResult());
            diagnosticResult.getMeasureResultList().add(measureResult);
        }
        return new ArrayList<>(resultMap.values());
    }

    //根据用户openid以及当前排到的科室号，医生电脑显示相对应的人的能够在这个科室体检的项目的信息不包括结果
    //患者第一次体检
    public Map<String, Object> getDepartmentItem(Integer reservationId, Integer doctorId) {
        Map<String,Object> res = new HashMap<>();
        List<DepartmentItemDto> departmentItemDto=new ArrayList<>();
        try {
            //获取所有的项目和检测类型
            departmentItemDto=doctorMapper.getDepartmentItem(reservationId,doctorId);
            //将departmentItemDto类整理为measure类
            List<DiagnosticResult>data = change(departmentItemDto);
            String reservationName=reservationMapper.getReservationName(reservationId);
            res.put("reservationName",reservationName);
            res.put("reservationId",reservationId);
            res.put("data",data);
        }catch (Exception e){
            throw new ServiceException(Constants.CODE_500,"获取项目信息失败");
        }
        return res;
    }

    //获取该医生的历史诊断记录
    public List<HistoryDiagnostic> getHistoryDiagnostic(Integer doctorId) {
        List<HistoryDiagnostic> res = new ArrayList<>();
        try {
            res = doctorMapper.getHistoryDiagnostic(doctorId);
        } catch (Exception e) {
            throw new ServiceException(Constants.CODE_500, "获取历史诊断记录失败！");
        }
        return res;
    }

    //获取历史诊断信息，详细信息

    public Map<String,Object> getDiagnosticInfo(Integer reservationId, Integer doctorId) {
        Map<String,Object> res = new HashMap<>();
        List<DepartmentItemDto> departmentItemDto=new ArrayList<>();
        try {
            //获取所有的项目和检测类型
            departmentItemDto=doctorMapper.getDiagnosticInfo(reservationId,doctorId);
            //将departmentItemDto类整理为measure类
            List<DiagnosticResult>data = change(departmentItemDto);
            res.put("reservationId",reservationId);
            res.put("data",data);
        }catch (Exception e){
            throw new ServiceException(Constants.CODE_500,"获取项目信息失败");
        }
        return res;
    }
    //-------------对应检后---------
    public Map<String,Object> getDiagnosticByReservationId(Integer reservationId) {
        Map<String,Object> res = new HashMap<>();
        List<DepartmentItemDto> departmentItemDto;
        try {
            //获取所有的项目和检测类型
            departmentItemDto=doctorMapper.getDiagnosticByReservationId(reservationId);
            //将departmentItemDto类整理为measure类
            List<DiagnosticResult>data = change(departmentItemDto);
            res.put("reservationId",reservationId);
            res.put("data",data);
        }catch (Exception e){
            throw new ServiceException(Constants.CODE_500,"获取项目信息失败");
        }
        return res;
    }

    //保存表单
    //isSubmit=true代表医生提交诊断，不做修改，在保存的基础上修改订单的完成状态
    //isSubmit=false代表只是保存订单，不提交订单
    public boolean saveDiagnostic(SaveDiagnosticResultDto saveDiagnosticResultDto,boolean isSubmit) {
        Integer reservationId = saveDiagnosticResultDto.getReservationId();
        Integer doctorId = saveDiagnosticResultDto.getDoctorId();
        List<DiagnosticResult> data = saveDiagnosticResultDto.getData();
        //System.out.println("reservationId:"+reservationId+"doctorId:"+doctorId);
        //首先根据reservationId和doctorId判断是更新还是插入，然后分别进行操作
        List<Diagnostic> diagnosticList = new ArrayList<>();
        diagnosticList = doctorMapper.diagnosticIsExist(reservationId,doctorId);

        if (diagnosticList.size()==0){
            //无数据则插入
            try {
                System.out.println("================================插入表单");
                for (Integer i = 0; i < data.size(); i++) {
                    DiagnosticResult diagnosticResult = data.get(i);
                    //插入diagnostic表
                    Diagnostic diagnostic = new Diagnostic(null, reservationId, diagnosticResult.getItemId(), doctorId, diagnosticResult.getDiagnosticResult(), null);
                    diagnosticMapper.insert(diagnostic);
                    System.out.println("=====================插入后返回的诊断id:" + diagnostic.getDiagnosticId());

                    //若为提交，则传入订单号以及项目号，更新该订单的项目的检测结果
                    if(isSubmit==true){
                        reservationItemMapper.changeReservationItemStatus(reservationId,diagnosticResult.getItemId());
                    }

                    //提取该项目的测量数据
                    List<MeasureResult> measureResultList = data.get(i).getMeasureResultList();
                    //插入测量数据
                    for (Integer j = 0; j < measureResultList.size(); j++) {
                        MeasureResult measureResult = measureResultList.get(j);
                        Measure measure = new Measure(null, measureResult.getMeasureKindId(), diagnostic.getDiagnosticId(), doctorId, measureResult.getMeasureResult(), null);
                        measureMapper.insert(measure);
                    }
                }
                return true;
            }catch (Exception e){
                throw new ServiceException(Constants.CODE_600,"保存数据插入时发生错误！");
            }
        }else {
            //有数据则更新
            //for循环诊断结果，先插入诊断表，再提取其中的
            System.out.println("================================更新表单");
            for (Integer i = 0; i < data.size(); i++) {
                DiagnosticResult diagnosticResult = data.get(i);
                Integer diagnosticId = diagnosticList.get(i).getDiagnosticId();
                //插入diagnostic表
                Diagnostic diagnostic = new Diagnostic(diagnosticId, reservationId, diagnosticResult.getItemId(), doctorId, diagnosticResult.getDiagnosticResult(), null);
                    try {
                        diagnosticMapper.updateById(diagnostic);
                        //若为提交，则传入订单号以及项目号，更新该订单的项目的检测结果
                        if(isSubmit==true){
                            reservationItemMapper.changeReservationItemStatus(reservationId,diagnosticResult.getItemId());
                        }
                    }catch (Exception e){
                        throw new ServiceException(Constants.CODE_600,"点击保存，更新数据时发生错误！");
                    }
                    //提取该项目的测量数据
                    List<MeasureResult> measureResultList = data.get(i).getMeasureResultList();
                //更新测量数据
                for (Integer j = 0; j < measureResultList.size(); j++) {
                    MeasureResult measureResult = measureResultList.get(j);
                    if(measureResult.equals("")||measureResult==null){
                        throw new ServiceException(Constants.CODE_600,"存在空值，更新失败！");
                    }
                    try {
                        measureMapper.updateResult(measureResult.getMeasureKindId(),diagnosticId,doctorId,measureResult.getMeasureResult());
                    }catch (Exception e){
                        throw new ServiceException(Constants.CODE_600,"点击保存，更新数据时发生错误！");
                    }
                }
            }
            return true;

        }


    }



}
